package sw

import chisel3._
import chisel3.util._
//import chisel3.util.experimental.loadMemoryFromFile
import scala.io.Source
import common.Consts._

class ImemPortIo extends Bundle {
  val addr = Input(UInt(WORD_LEN.W))
  val inst = Output(UInt(WORD_LEN.W))
}

class DmemPortIo extends Bundle {
  val addr  = Input(UInt(WORD_LEN.W))
  val rdata = Output(UInt(WORD_LEN.W))
  val wen   = Input(Bool())           // 追加
  val wdata = Input(UInt(WORD_LEN.W)) // 追加
}

class Memory extends Module {

  val io = IO(new Bundle {
    val imem = new ImemPortIo
    val dmem = new DmemPortIo
  })

  val mem = Mem(16384, UInt(8.W))
  //loadMemoryFromFile(mem, "src/hex/sw.hex")
  var fileLines = Source.fromFile("src/hex/sw.hex").getLines().toList
  for((line, index) <- fileLines.zipWithIndex) {
    val num: Int = Integer.parseInt(line, 16)
    val idxBits: UInt = index.asUInt
    val lineBits: UInt = num.asUInt
    mem(index) := lineBits
    //chisel3.printf(p"fromFile: Index: ${idxBits}, Content: ${lineBits}, mem: ${mem(index)}\n")
  }

  io.imem.inst := Cat(
    mem(io.imem.addr + 3.U(WORD_LEN.W)), 
    mem(io.imem.addr + 2.U(WORD_LEN.W)),
    mem(io.imem.addr + 1.U(WORD_LEN.W)),
    mem(io.imem.addr)
  )
  io.dmem.rdata := Cat(
    mem(io.dmem.addr + 3.U(WORD_LEN.W)),
    mem(io.dmem.addr + 2.U(WORD_LEN.W)), 
    mem(io.dmem.addr + 1.U(WORD_LEN.W)),
    mem(io.dmem.addr)
  )
  chisel3.printf("io.imem.addr=0x%x,  io.imem.inst=0x%x,  io.dmem.addr=0x%x,  io.dmem.rdata=0x%x.\n",
                 io.imem.addr,  io.imem.inst,  io.dmem.addr, io.dmem.rdata)

  when(io.dmem.wen){
    mem(io.dmem.addr)       := io.dmem.wdata( 7, 0)
    mem(io.dmem.addr + 1.U) := io.dmem.wdata(15, 8)
    mem(io.dmem.addr + 2.U) := io.dmem.wdata(23,16)
    mem(io.dmem.addr + 3.U) := io.dmem.wdata(31,24)
    chisel3.printf("io.imem.dmem=0x%x,  io.imem.wdata=0x%x.\n",io.dmem.addr, io.dmem.wdata)
  }
}
